package com.songhuan.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songhuan.web.dto.*;
import com.songhuan.web.dto.query.*;
import com.songhuan.web.entity.*;
import com.songhuan.web.mapper.*;
import com.songhuan.web.service.*;
import com.songhuan.web.tools.dto.*;
import com.songhuan.web.tools.Extension;
import com.songhuan.web.tools.exception.CustomException;
import com.songhuan.web.dto.AppUserDto;
import com.songhuan.web.dto.OrganizationDto;
import com.songhuan.web.dto.OrganizationRelativeUserDto;
import com.songhuan.web.dto.query.OrganizationRelativeUserPagedInput;
import com.songhuan.web.entity.AppUser;
import com.songhuan.web.entity.Enums;
import com.songhuan.web.entity.Organization;
import com.songhuan.web.entity.OrganizationRelativeUser;
import com.songhuan.web.mapper.AppUserMapper;
import com.songhuan.web.mapper.OrganizationMapper;
import com.songhuan.web.mapper.OrganizationRelativeUserMapper;
import com.songhuan.web.service.OrganizationRelativeUserService;
import com.songhuan.web.tools.dto.PagedResult;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import lombok.SneakyThrows;
import com.songhuan.web.tools.*;

/**
 * 班级关联功能实现类
 */
@Service
public class OrganizationRelativeUserServiceImpl extends ServiceImpl<OrganizationRelativeUserMapper, OrganizationRelativeUser> implements OrganizationRelativeUserService {

    /**
     * 操作数据库AppUser表mapper对象
     */
    @Autowired
    private AppUserMapper _AppUserMapper;
    /**
     * 操作数据库的OrganizationRelativeUser表mapper对象
     */
    @Autowired
    private OrganizationRelativeUserMapper _OrganizationRelativeUserMpper;


    @Autowired
    private OrganizationMapper _OrganizationMapper;


    /**
     * 班级关联分页查询
     */
    @SneakyThrows
    @Override
    public PagedResult<OrganizationRelativeUserDto> List(OrganizationRelativeUserPagedInput input) {


        //声明一个支持班级关联查询的(拉姆达)表达式
        LambdaQueryWrapper<OrganizationRelativeUser> queryWrapper = Wrappers.<OrganizationRelativeUser>lambdaQuery()
                .eq(input.getId() != null && input.getId() != 0, OrganizationRelativeUser::getId, input.getId())
                .eq(input.getCreatorId() != null, OrganizationRelativeUser::getCreatorId, input.getCreatorId());
        //如果前端搜索传入查询条件则拼接查询条件
        if (input.getUserId() != null) {
            queryWrapper = queryWrapper.eq(OrganizationRelativeUser::getUserId, input.getUserId());
        }
        if (input.getOrganizationId() != null) {
            queryWrapper = queryWrapper.eq(OrganizationRelativeUser::getOrganizationId, input.getOrganizationId());
        }

        if (Extension.isNotNullOrEmpty(input.getRemark())) {
            queryWrapper = queryWrapper.eq(OrganizationRelativeUser::getRemark, input.getRemark());
        }
        if (input.getAuditStatus() != null) {
            queryWrapper = queryWrapper.eq(OrganizationRelativeUser::getAuditStatus, input.getAuditStatus());
        }

        //按创建时间从大到小排序 最新的显示在最前面
        queryWrapper = queryWrapper.orderByDesc(OrganizationRelativeUser::getCreationTime);
        //构建一个分页查询的model
        Page<OrganizationRelativeUser> page = new Page<>(input.getPage(), input.getLimit());


        //从数据库进行分页查询获取班级关联数据
        IPage<OrganizationRelativeUser> pageRecords = _OrganizationRelativeUserMpper.selectPage(page, queryWrapper);

        //获取所有满足条件的数据行数
        Long totalCount = _OrganizationRelativeUserMpper.selectCount(queryWrapper);

        //把OrganizationRelativeUser实体转换成OrganizationRelativeUser传输模型
        List<OrganizationRelativeUserDto> items = Extension.copyBeanList(pageRecords.getRecords(), OrganizationRelativeUserDto.class);
        for (OrganizationRelativeUserDto item : items) {

            //查询出关联的创建用户信息
            AppUserDto CreatorAppUserDTO = new AppUserDto();
            AppUser CreatorAppUserEntity = _AppUserMapper.selectOne(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getId, item.getCreatorId()));
            if (CreatorAppUserEntity != null) {
                BeanUtils.copyProperties(CreatorAppUserDTO, CreatorAppUserEntity);
                item.setCreatorAppUserDto(CreatorAppUserDTO);
            }


            //查询出关联的AppUser表信息
            AppUserDto UserDTO = new AppUserDto();
            AppUser UserEntity = _AppUserMapper.selectOne(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getId, item.getUserId()));
            if (UserEntity != null) {
                BeanUtils.copyProperties(UserDTO, UserEntity);
                item.setUserDto(UserDTO);
            }


            //查询出关联的Organization表信息
            OrganizationDto OrganizationDTO = new OrganizationDto();
            Organization OrganizationEntity = _OrganizationMapper.selectOne(Wrappers.<Organization>lambdaQuery().eq(Organization::getId, item.getOrganizationId()));
            if (OrganizationEntity != null) {
                BeanUtils.copyProperties(OrganizationDTO, OrganizationEntity);
                item.setOrganizationDto(OrganizationDTO);
            }

        }

        //返回一个分页结构给前端
        return PagedResult.GetInstance(items, totalCount);

    }

    /**
     * 单个班级关联查询
     */
    @SneakyThrows
    @Override
    public OrganizationRelativeUserDto Get(OrganizationRelativeUserPagedInput input) {
        if (input.getId() == null) {
            return new OrganizationRelativeUserDto();
        }
        PagedResult<OrganizationRelativeUserDto> pagedResult = List(input);
        return pagedResult.getTotalCount() > 0 ? pagedResult.getItems().stream().findFirst().get() : new OrganizationRelativeUserDto();
    }

    /**
     * 班级关联创建或者修改
     */
    @SneakyThrows
    @Override
    public OrganizationRelativeUserDto CreateOrEdit(OrganizationRelativeUserDto input) {

        //声明一个班级关联实体
        OrganizationRelativeUser OrganizationRelativeUser = new OrganizationRelativeUser();

        //把前端传入的input参数拷贝到班级关联实体
        BeanUtils.copyProperties(OrganizationRelativeUser, input);

        //调用数据库的增加或者修改方法
        saveOrUpdate(OrganizationRelativeUser);

        //定义一个返回给前端的班级关联传输模型
        OrganizationRelativeUserDto OrganizationRelativeUserDto = new OrganizationRelativeUserDto();

        //同理把操作的班级关联实体拷贝给班级关联传输模型
        BeanUtils.copyProperties(OrganizationRelativeUserDto, OrganizationRelativeUser);

        //把传输模型返回给前端
        return OrganizationRelativeUserDto;
    }

    /**
     * 班级申请
     */
    @SneakyThrows
    @Override
    public void Apply(OrganizationRelativeUserDto input) {

        //判断用户是否存在在一个班级中
        AppUser appUser = _AppUserMapper.selectById(input.getUserId());
        if (Extension.isNotNullOrZero(appUser.getOrganizationId())) {
            throw new CustomException("用户已经存在在一个班级中,请勿重复申请");
        }
        //判断用户是否存在待审核的申请记录
        LambdaQueryWrapper<OrganizationRelativeUser> queryWrapper = Wrappers.<OrganizationRelativeUser>lambdaQuery()
                .eq(OrganizationRelativeUser::getUserId, input.getUserId())
                .eq(OrganizationRelativeUser::getAuditStatus, Enums.AuditStatus.待审核);
        if (_OrganizationRelativeUserMpper.selectCount(queryWrapper) > 0) {
            throw new CustomException("用户已经存在待审核的申请记录,请勿重复申请");
        }
        input.setAuditStatus(Enums.AuditStatus.待审核.index());

        //声明一个班级关联实体
        OrganizationRelativeUser OrganizationRelativeUser = new OrganizationRelativeUser();

        //把前端传入的input参数拷贝到班级关联实体
        BeanUtils.copyProperties(OrganizationRelativeUser, input);

        //调用数据库的增加或者修改方法
        saveOrUpdate(OrganizationRelativeUser);

    }
    /**
     * 班级申请成功
     */
    @SneakyThrows
    @Override
    public void ApplySuccess(OrganizationRelativeUserDto input){

        input.setAuditStatus(Enums.AuditStatus.审核通过.index());

        input.setReplyContent("班级同意您的加入");
        //修改用户的班级信息
        AppUser appUser = _AppUserMapper.selectById(input.getUserId());
        appUser.setOrganizationId(input.getOrganizationId());
        _AppUserMapper.updateById(appUser);

        //声明一个班级关联实体
        OrganizationRelativeUser OrganizationRelativeUser = new OrganizationRelativeUser();

        //把前端传入的input参数拷贝到班级关联实体
        BeanUtils.copyProperties(OrganizationRelativeUser, input);

        //调用数据库的增加或者修改方法
        saveOrUpdate(OrganizationRelativeUser);
    }

    public void updateOrganizationRelativeUser(AppUserDto appUserDto) {

        _OrganizationRelativeUserMpper.update(null, new LambdaUpdateWrapper<OrganizationRelativeUser>()
                .eq(OrganizationRelativeUser::getUserId, appUserDto.getId())
                .set(OrganizationRelativeUser::getOrganizationId, appUserDto.getOrganizationId())
        );

    }

}
